// List concept implementation
// Copyright 2006 (C) Ralph Thomas

#include <util/concepts/list.h>
#include <vector>
#include <adobe/copy_on_write.hpp>

namespace util {
	namespace concept {
		ListInterface::~ListInterface() {}
		List get_list( const adobe::value_t& v ) {
			typedef std::vector<int> int_vector;
			typedef std::vector<std::string> string_vector;
			typedef std::vector<double> double_vector;
			typedef adobe::copy_on_write<int_vector> cow_int_vector;
			typedef adobe::copy_on_write<string_vector> cow_string_vector;
			typedef adobe::copy_on_write<double_vector> cow_double_vector;
		
			//
			// Since we don't have real concept support, this works by
			// checking to see if the given value is one of the types
			// that we already know meets the requirements for List.
			//
			if( v.type() == typeid(adobe::array_t) )
				return List(ListInstance( new ListProxy<adobe::array_t>( v.get<adobe::array_t>() ) ));
			if( v.type() == typeid(ListInstance) )
				return List(v.get<ListInstance>());
			if( v.type() == typeid(string_vector) )
				return List(ListInstance( new ListProxy<string_vector>( v.get<string_vector>() ) ));
			if( v.type() == typeid(int_vector) )
				return List(ListInstance( new ListProxy<int_vector>( v.get<int_vector>() ) ));
			if( v.type() == typeid(double_vector) )
				return List(ListInstance( new ListProxy<double_vector>( v.get<double_vector>() ) ));
			if( v.type() == typeid(cow_string_vector) )
				return List(ListInstance( new ListProxyPtr<cow_string_vector>( v.get<cow_string_vector>() ) ));
			if( v.type() == typeid(cow_int_vector) )
				return List(ListInstance( new ListProxyPtr<cow_int_vector>( v.get<cow_int_vector>() ) ));
			if( v.type() == typeid(cow_double_vector) )
				return List(ListInstance( new ListProxyPtr<cow_double_vector>( v.get<cow_double_vector>() ) ));
			return List();
		}	
	}
}
